package com.me.common.util.io;

import org.apache.commons.io.FileUtils;

import java.io.*;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.Enumeration;
import java.util.Objects;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * IO 工具类
 *
 * @author ME
 * @date 2020/10/24
 */
public class IoUtils {

    /**
     * 把 字符串 写入文件
     */
    public static void writeToFile(String path, String key) throws IOException {
        try (PrintWriter writer = new PrintWriter(new FileWriter(path), true)) {
            writer.println(key);
        }
    }

    /**
     * 读取文件内容
     *
     * @param path 不带 `/` 则从 classpath开始查找
     */
    public static String readFromFile(String path) throws IOException {
        StringBuilder sb = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new FileReader(IoUtils.getPathFromClasspath(path)))) {
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        }

        return sb.toString();
    }

    /**
     * 对于 SpringBoot jar，读取文件内容
     *
     * @param path 不带 `/` 则从 classpath开始查找
     */
    public static String readFromJar(String path) throws IOException {
        StringBuilder sb = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(IoUtils.class.getResourceAsStream(path)))) {
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        }

        return sb.toString();
    }

    /**
     * 从指定 jar 复制指定文件到本地
     *
     * @param jarFilePath       jar包的路径
     * @param innerFileName     jar包里文件的名称，含目录（META-INF/maven/pom.xml）
     * @param descFile          目标文件，即复制到哪
     */
    public static void copyFileInJar(String jarFilePath, String innerFileName, String descFile) throws IOException {
        try (JarFile jarFile = new JarFile(jarFilePath)) {
            Enumeration<JarEntry> myEnum = jarFile.entries();
            while (myEnum.hasMoreElements()) {
                // jar包里的文件：
                JarEntry innerJarEntry = myEnum.nextElement();
                if (innerFileName.equals(innerJarEntry.getName())) {
                    // try (InputStream input = jarFile.getInputStream(innerJarEntry); FileOutputStream fos = new FileOutputStream(descFile)) {
                    //     byte[] b = new byte[1024];
                    //     int len;
                    //     while ((len = input.read(b)) != -1) {
                    //         fos.write(b, 0, len);
                    //     }
                    //     fos.flush();
                    // }
                    try (InputStream input = jarFile.getInputStream(innerJarEntry)) {
                        FileUtils.copyToFile(input, new File(descFile));
                    }
                }
            }
        }
    }

    /**
     * 从指定 jar 复制指定文件到本地
     *
     * @param jarFilePath       jar包的路径
     * @param innerFileName     jar包里文件的名称，含目录（META-INF/maven/pom.xml）
     * @param descFile          目标文件，即复制到哪
     */
    public static void copyFileInJar2(String jarFilePath, String innerFileName, String descFile) throws IOException {
        InputStream inputStream = getInputStream4FileInJar(jarFilePath, innerFileName);
        FileUtils.copyToFile(inputStream, new File(descFile));
    }

    /**
     * 获取 指定jar 中 指定文件的 IO输入流
     *
     * @param jarFilePath       jar包的路径
     * @param innerFileName     jar包里文件的名称，含目录（META-INF/maven/pom.xml）
     */
    public static InputStream getInputStream4FileInJar(String jarFilePath, String innerFileName) throws IOException {
        URL url = new URL("jar:file:" + jarFilePath + "!/" + innerFileName);
        JarURLConnection jarConnection = (JarURLConnection) url.openConnection();

        return jarConnection.getInputStream();
    }

    public static URL getURLFromClasspath(String filename) {
        return Objects.requireNonNull(IoUtils.class.getClassLoader().getResource(filename));
    }

    /**
     * 获取文件的完整路径，{@link com.me.study.javaCore.io.TestFilePath#main(String[])}    <p>
     *  /D:/workspace/testME/testJDK8/target/classes/test-file.txt
     *
     * @param filename 不带 `/` 则从 classpath开始查找
     * @return
     */
    public static String getPathFromClasspath(String filename) {
        return Objects.requireNonNull(IoUtils.class.getClassLoader().getResource(filename)).getPath();
    }

    /**
     * 获取文件的完整路径，包含 getQuery() 部分 <p>
     *  /D:/workspace/testME/testJDK8/target/classes/test-file.txt?id=123456
     *
     * @param filename
     * @return
     */
    public static String getFilePathFromClasspath(String filename) {
        return Objects.requireNonNull(IoUtils.class.getClassLoader().getResource(filename)).getFile();
    }

}
